<?php

namespace JsonLowCode\UI;

use JsonLowCode\Schema;
use JsonLowCode\Traits\Events\HasModelValueEvent;
use JsonLowCode\Traits\Events\HasOnClose;
use JsonLowCode\Traits\Props\HasAnimated;
use JsonLowCode\Traits\Props\HasClosable;
use JsonLowCode\Traits\Props\HasDefaultValue;
use JsonLowCode\Traits\Props\HasSize;
use JsonLowCode\Traits\Props\HasTrigger;
use JsonLowCode\Traits\Props\HasValue;
use JsonLowCode\Traits\Slots\HasSlotPrefix;
use JsonLowCode\Traits\Slots\HasSlotSuffix;

/**
 * 组件 - 标签页 Tabs
 * @method static Tabs make(mixed $children = null) Tabs组件
 */
class Tabs extends Schema
{
    protected string $componentName = "AppTabs";

    //props
    use HasAnimated, HasDefaultValue, HasClosable, HasTrigger, HasValue, HasSize;
    //slots
    use HasSlotPrefix, HasSlotSuffix;
    //events
    use HasOnClose, HasModelValueEvent;

    protected array $options = [];
    protected array $slotOptions = [];

    public function __construct(mixed $children = null)
    {
        parent::__construct();
        $this->line();
        $this->children($children);
    }

    /**
     * 设置标签类型
     * @param string $type 'bar' | 'line' | 'card' | 'segment'
     * @return $this
     */
    public function type(string $type = 'bar' | 'line' | 'card' | 'segment'): Tabs
    {
        return $this->prop('type',$type);
    }

    /**
     * 设置条形类型的标签页
     * @return $this
     */
    public function bar(): Tabs
    {
        return $this->type('bar');
    }

    /**
     * 设置线形类型的标签页
     * @return $this
     */
    public function line(): Tabs
    {
        return $this->type('line');
    }

    /**
     * 设置卡片类型的标签页
     * @return $this
     */
    public function card(): Tabs
    {
        return $this->type('card');
    }

    /**
     * 设置分段类型的标签页
     * @return $this
     */
    public function segment(): Tabs
    {
        return $this->type('segment');
    }

    /**
     * 设置 flex 布局下主轴的排列方式，tabs标签组件只对 'line' 和 'bar' 类型生效
     * @param string $justifyContent 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly'
     * @return $this
     */
    public function justifyContent(string $justifyContent = 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly' ): static
    {
        return $this->prop('justify-content',$justifyContent);
    }

    /**
     * 设置组件 v-model:value 双向绑定数据源
     * @param mixed $value
     * @return $this
     */
    public function modelValue(mixed $value): static
    {
        return $this->prop('v-model:value', $value);
    }

    /**
     * 标签条的宽度
     * @param int $barWidth
     * @return $this
     */
    public function barWidth(int $barWidth): static
    {
        return $this->prop('bar-width',$barWidth);
    }

    /**
     * 面板的类名
     * @param string $paneClass
     * @return $this
     */
    public function paneClass(string $paneClass): static
    {
        return $this->prop("pane-class",$paneClass);
    }

    /**
     * 面板的样式
     * @param string|array $paneStyle
     * @return $this
     */
    public function paneStyle(string|array $paneStyle): static
    {
        return $this->prop("pane-style",$paneStyle);
    }

    /**
     * 标签的样式
     * @param string|array $tabStyle
     * @return $this
     */
    public function tabStyle(string|array $tabStyle): static
    {
        return $this->prop("tab-style",$tabStyle);
    }

    /**
     * 全部标签最左和最右的 padding
     * @param string|int $tabsPadding
     * @return $this
     */
    public function tabsPadding(string|int $tabsPadding): static
    {
        return $this->prop("tabs-padding",$tabsPadding);
    }

    /**
     * 添加标签的回调函数
     * @param string $value 函数 ()=>{}
     * @return $this
     */
    public function onAdd(string $value = "()=>{}"): static
    {
        return $this->events("onAdd",$value);
    }

    /**
     * 切换标签之前的钩子函数，返回 false 或 promise resolve false 或 promise reject 会阻止切换
     * @param string $value 函数 (name: string | number, oldName: string | number | null) => boolean | Promise<boolean>
     * @return $this
     */
    public function onBeforeLeave(string $value = "() => {}"): static
    {
        return $this->events("onBeforeLeave",$value);
    }

    /**
     * 设置标签页
     * @param string $tab
     * @param mixed $children
     * @return TabPane
     */
    public function tab(string $tab, mixed $children): TabPane
    {
        $count = count($this->options);
        $tabPane = new TabPane($count, $tab);
//        $tabPane->children($children);
        $tabPane->displayDirective("show");
        if(is_callable($children)){
            $result =  call_user_func($children,$tabPane);
            $this->slotOptions[$tab] = $result;
        }else{
            $this->slotOptions[$tab] = $children;
        }
        $this->addOptions([
            'name'=>$count,
            'tab'=>$tab
        ]);
//        $this->children($tabPane);
        return $tabPane;
    }

    public function getOptionCount(): int
    {
        return count($this->options);
    }

    public function addOptions($option): static
    {
        $this->options[] = $option;
        return $this;
    }

    public function addSlotOptions($key, $value): static
    {
        $this->slotOptions[$key] = $value;
        return $this;
    }

    /**
     * 发生改变时的回调函数
     * @param string $key 键
     * @param string $event 事件
     * @return $this
     */
    public function onUpdateKey(string $key = "", string $event = ""): static
    {
        return $this->events("onUpdate:".$key,$event);
    }

    /**
     * @return array
     */
    public function jsonSerialize(): array
    {
        $options = $this->options;
        foreach ($options as $option){
            $this->slot("tab_".$option['name'], $option['tab']);
            $this->slot("slot_".$option['name'], $this->slotOptions[$option['tab']]);
        }
        $this->prop("options", $options);
        return parent::jsonSerialize();
    }


}
